﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using PathFinder;


namespace QuestPrototype
{
    public enum CharacterState { idle, walking }
    class Character 
    {
        
        #region Character fields
        private CharacterState state;
        private Dictionary<String, Animation> animations;
        private string current_animation;
        private Rectangle location;
        private Vector2 walkTo;
        private int walkSpeed;
        private List<Stop> path;
        #endregion

        #region Character Constructors
        public Character(Rectangle _init_location, Dictionary<string, Animation> _animations, string _init_animation, int _walkSpeed)
        {
            this.location = _init_location;
            this.animations = _animations;
            this.current_animation = _init_animation;
            this.walkSpeed = _walkSpeed;
            this.walkTo = new Vector2(-1, -1);
        }
        public Character()
        {
            
        }
        
        #endregion

        #region Character Update
        public void Update(GameTime gameTime, float Size)
        {
            switch (state)
            {
                case CharacterState.idle: 
                        break;
                   
                case CharacterState.walking:
                        if (characterWalk(Size))
                        {
                            state = CharacterState.idle;
                            current_animation = "idle";
                            animations["idle"].stop();
                        }
                        break;
            }
            animations[current_animation].Update(gameTime);
        }   
        #endregion

        #region Character Draw
        public void Draw(SpriteBatch spriteBatch, float Size)
        {
            Rectangle AccurateLocation = new Rectangle(location.X - (int)(location.Width * Size) / 2, location.Y - (int)(location.Height * Size), (int)(location.Width * Size), (int)(location.Height * Size));
            animations[current_animation].Draw(spriteBatch, AccurateLocation);
        }
        #endregion

        /// <summary>
        /// Auxliairy functions: pathfinding functions are here
        /// </summary>
    

        /// <summary>
        /// naive implemention of pathfinding: character just adds to X and Y values of its location
        /// just a placeholder
        /// </summary>
        /// <returns></returns>
        private bool characterWalk(float Size)
        {
            bool RC = false;
            if (path == null)
            {
                walkTo.X = -1;
                walkTo.Y = -1;
                return true;
            }
            Vector2 CurrentLocation = new Vector2(location.X, location.Y);

            if (path.Count > 0 && ((walkTo.X == location.X && walkTo.Y == location.Y) || ((walkTo.X == -1 && walkTo.Y == -1))))
            {
                Stop TempStop = path.First<Stop>();
                walkTo = TempStop.Point;
                switch (TempStop.DirectioFromLastPoint)
                {
                    case 1:
                        current_animation = "WalkLeft";
                        StartAnimation();
                        break;
                    case 2:
                        current_animation = "WalkRight";
                        StartAnimation();
                        break;
                    case 3:
                        current_animation = "WalkRight";
                        StartAnimation();
                        break;
                    case 4:
                        current_animation = "WalkLeft";
                        StartAnimation();
                        break;
                    case 6:
                        current_animation = "WalkRight";
                        StartAnimation();
                        break;
                    case 7:
                        current_animation = "WalkLeft";
                        StartAnimation();
                        break;
                    case 8:
                        current_animation = "WalkRight";
                        StartAnimation();
                        break;
                    case 9:
                        current_animation = "WalkRight";
                        StartAnimation();
                        break;
                    default:
                        current_animation = "WalkRight";
                        StartAnimation();
                        break;
                }
                path.RemoveAt(0);
            }
            

            if ((Vector2.Distance(walkTo, CurrentLocation) <= walkSpeed))
            {
                location.X = (int)Math.Round(walkTo.X);
                location.Y = (int)Math.Round(walkTo.Y);
            }
            else
            {
                Vector2 velocity = Vector2.Subtract(walkTo, CurrentLocation);
                velocity.Normalize();
                velocity = Vector2.Multiply(velocity, walkSpeed);
                CurrentLocation = Vector2.Add(CurrentLocation, velocity);
                location.X = (int)CurrentLocation.X;
                location.Y = (int)CurrentLocation.Y;
            }

            if (location.X == walkTo.X && location.Y == walkTo.Y && path.Count == 0)
            {
                walkTo.X = -1;
                walkTo.Y = -1;
                path = null;
                RC = true;
            }
            return RC;
            //return true if destination is reached
        }

       

        /// <summary>
        /// make a character walk a streight line from current location (location) to current target (walkTo)
        /// </summary>
        /// <returns></returns>
        private bool characterWalkLine()
        {
            throw new NotImplementedException("Function Doesn't Work!");
        }

        public System.Drawing.Point GetPosition()
        {
            return new System.Drawing.Point(location.X, location.Y);
        }

        public void SetPath(List<Stop> path)
        {
            walkTo.X = -1;
            walkTo.Y = -1;
            this.path = path;
        }

        public int PathCount()
        {
            if (path != null)
            {
                return path.Count;
            }
            else
            {
                return -1;
            }
        }

        public void StartAnimation()
        {
            animations[current_animation].loop();
        }

        public void Walk()
        {
            state = CharacterState.walking;
        }


        public void ExportToXML()
        {
            

        }

        public void ImportFromXML()
        {
            throw new NotImplementedException();
        }
    }
}
